package com.exampleyyy.demoyyy.GuoLv;
import com.alibaba.fastjson.JSON;

import com.exampleyyy.demoyyy.common.BaseContext;
import com.exampleyyy.demoyyy.common.R;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.*;
// 正确的过滤器导入
// import java.util.logging.Filter;
// 错误的过滤器导入
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.regex.Pattern;
//网页过滤器   filterName 过滤器的名字 urlPatterns 限制过滤范围  / 代表127.0.0.1:8081后面的第一个斜杠
// * 代表所有路由
@Slf4j
@WebFilter(filterName="neidianziGuoLV",urlPatterns = "/*")
public class logincheckGuolv  implements Filter {
    // 1.普通类变成过滤器类 ,implements 生效  Filter 过滤器
    // 2.划定范围,白名单,在白名单中的路由或者接口,直接放行到控制层,不需要验证
    String[] BaiMingDan = new String[]{ // 外部路由或者接口,直接放行
            "/employee/login",
            "/employee/logout",
            "/user/sendMsg",
            "/user/login",
            "/user/loginout",
            "/front/page/login.html",
            "/backend/page/login/login.html",
            "/front/css/.*?",
            "/front/js/.*?",
            "/front/images/.*?",
            "/front/favicon.ico",
            "/backend/css/.*?",
            "/backend/js/.*?",
            "/backend/images/.*?",
            "/backend/plugins/.*?",
            "/backend/favicon.ico",
            "/front/styles/.*?",
            "/front/api/.*?",
            "/backend/styles/.*?",
            "/backend/api/.*?",
            "/front/fonts/PingFangSC-Medium.ttf",
            "/",  // 过滤器放行 /
            "/admin"  // 过滤器放行 /admin
    };
    //重写过滤器函数
    @Override
    public  void  doFilter(ServletRequest QingQiu,
                           ServletResponse XiangYing, FilterChain FangXing)
            throws IOException, ServletException {
        // 参数1. 请求参数ServletRequest类型  参数名 QingQiu
        // 参数2. 响应参数ServletResponse类型 参数名 XiangYing
        // 参数3. 放行参数FilterChain类型     参数名 FangXing
        //1.判断来的这个请求接口，在不在白名单中，在白名单中，直接放行，放行到控制层
        //1.1 通过请求对象获取请求接口,构建请求对象,构建响应对象
        HttpServletRequest  request = (HttpServletRequest) QingQiu;
        HttpServletResponse response = (HttpServletResponse) XiangYing;
        String realURI = request.getRequestURI();
        log.info("拦截到请求: {}", realURI);

        //2.循环白名单,将白名单中的每一个元素,与 获取的URI地址对比
        for( String meiyige:BaiMingDan){
            // 用正则表达式去匹配Pattern.matches
            boolean  result = Pattern.matches(meiyige,realURI);
            if(result){
                // 如果结果为真,说明在白名单中,放行到控制层
                FangXing.doFilter(request,response);
                log.info("这个地址是放行地址,在白名单中: {}", realURI);
                return;
            }
        }

        // 检查是否为前端或后端页面请求
        boolean isFrontendRequest = realURI.startsWith("/front/");
        boolean isBackendRequest = realURI.startsWith("/backend/");

        // 检查是否为员工相关接口
        boolean isEmployeeApi = realURI.startsWith("/employee") && !realURI.equals("/employee/login") && !realURI.equals("/employee/logout");
        // 检查是否为用户相关接口
        boolean isUserApi = realURI.startsWith("/user") && !realURI.equals("/user/login") && !realURI.equals("/user/sendMsg") && !realURI.equals("/user/loginout");

        // 检查登录状态
        Long employeeId = (Long) request.getSession().getAttribute("员工信息id");
        Long userId = (Long) request.getSession().getAttribute("用户信息id");
        boolean isEmployeeLoggedIn = employeeId != null;
        boolean isUserLoggedIn = userId != null;

        // 3. 如果访问前端页面或相关接口
        if (isFrontendRequest) {
            // 用户已登录前端
            if (isUserLoggedIn) {
                log.info("用户已经登录，用户id为：{}", userId);
                BaseContext.setCurrentId(userId);
                FangXing.doFilter(request, response);
                return;
            } else {
                // 用户未登录，跳转到登录页面
                log.info("访问前端接口但未登录: {}", realURI);
                // 如果是页面请求，重定向到登录页；否则返回JSON错误
                if (realURI.endsWith(".html") && !realURI.equals("/front/page/login.html")) {
                    response.sendRedirect("/front/page/login.html");
                } else {
                    response.getWriter().write(JSON.toJSONString(R.error(0,"notlogin","用户未登录")));
                }
                return;
            }
        }

        // 4. 如果访问后端页面或相关接口
        if (isBackendRequest) {
            // 员工已登录
            if (isEmployeeLoggedIn) {
                log.info("员工已经登录，员工id为：{}", employeeId);
                BaseContext.setCurrentId(employeeId);
                FangXing.doFilter(request, response);
                return;
            } else {
                // 员工未登录，返回错误信息
                log.info("访问后端接口但未登录: {}", realURI);
                // 如果是页面请求，重定向到登录页；否则返回JSON错误
                if (realURI.endsWith(".html") && !realURI.equals("/backend/page/login/login.html")) {
                    response.sendRedirect("/backend/page/login/login.html");
                } else {
                    response.getWriter().write(JSON.toJSONString(R.error(0,"notlogin","员工未登录")));
                }
                return;
            }
        }

        // 3.如果访问员工相关接口
        if(isEmployeeApi) {
            // 员工已登录
            if(isEmployeeLoggedIn){
                log.info("员工已经登录，员工id为：{}", employeeId);
                BaseContext.setCurrentId(employeeId);
                FangXing.doFilter(request,response);
                return;
            } else {
                // 员工未登录，返回错误信息
                log.info("访问员工接口但未登录: {}", realURI);
                response.getWriter().write(JSON.toJSONString(R.error(0,"notlogin","员工未登录")));
                return;
            }
        }

        // 4. 如果访问用户相关接口
        if (isUserApi) {
            // 用户已登录
            if (isUserLoggedIn) {
                log.info("用户已经登录，用户id为：{}", userId);
                //将id存入线程变量
                BaseContext.setCurrentId(userId);
                FangXing.doFilter(request, response);
                return;
            } else {
                // 用户未登录，返回错误信息
                log.info("访问用户接口但未登录: {}", realURI);
                response.getWriter().write(JSON.toJSONString(R.error(0,"notlogin","用户未登录")));
                return;
            }
        }

        // 5. 其他情况，检查任一登录状态
        // 优先检查员工登录状态
        if(isEmployeeLoggedIn){
            //如果有session,说明处于登录状态,放行
            log.info("员工已经登录，员工id为：{}", employeeId);
            BaseContext.setCurrentId(employeeId);
            FangXing.doFilter(request,response);
            return;
        }

        // 然后检查用户登录状态
        if (isUserLoggedIn) {
            log.info("用户已经登录，用户id为：{}", userId);
            //将id存入线程变量
            BaseContext.setCurrentId(userId);
            FangXing.doFilter(request, response);
            return;
        }

        // 否则,你就是没有处于登录状态,返回一个错误
        log.info("这个地址是不在白名单中,且不处于登录状态,不放行,打回: {}", realURI);
        response.getWriter().write(JSON.toJSONString(R.error(0,"notlogin","未登录")));
        return;

    }
}